package com.cdp.web.controller.system;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.IService;
import com.cdp.common.core.domain.AjaxResult;
import com.cdp.common.core.domain.BaseEntity;
import com.cdp.common.core.domain.entity.*;
import com.cdp.common.core.redis.RedisCache;
import com.cdp.common.utils.SecurityUtils;
import com.cdp.system.mapper.SysCementMapper;
import com.cdp.system.mapper.SysMechanicalPerformanceMapper;
import com.cdp.system.service.*;
import com.google.common.base.Function;
import org.checkerframework.checker.index.qual.GTENegativeOne;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Field;
import java.sql.Timestamp;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * 平台访问记录控制器
 */
@RestController
@RequestMapping("/platform/visits")
public class PlatformVisitController {
    @Autowired
    private SysMechanicalPerformanceMapper sysMechanicalPerformanceMapper;

    @Autowired
    private SysCementMapper sysCementMapper;
    @Autowired
    private IRegionService regionService;


    @Autowired
    private IsysRegionService isysRegionService;
    @Autowired
    private ISysFlyashService sysFlyashService;

    @Autowired
    private ISysSandFinenesService sysSandFinenesService;

    @Autowired
    private ISysSandTypeService sysSandTypeService;

    @Autowired
    private ISysSandService sysSandService;

    @Autowired
    private ISysStoneGrainService sysStoneGrainService;

    @Autowired
    private ISysFlyashTypeService sysFlyashTypeService;

    @Autowired
    private ISysFlyashFinenessService sysFlyashFinenessService;

    @Autowired
    private ISysWaterReducerTypeService sysWaterReducerTypeService;

    @Autowired
    private ISysCementService sysCementService;

    @Autowired
    private ISysStoneService sysStoneService;

    @Autowired
    private ISysWaterReducerService sysWaterReducerService;

    @Autowired
    private ISysStoneSizeService stoneSizeService;

    @Autowired
    private ISysSourceNameService sysSourceNameService;
    @Autowired
    private ISysEfficiencyMerchantNameService sysEfficiencyMerchantNameService;


    @Autowired
    private ISysDeformationPerformanceService sysDeformationPerformanceService;

    @Autowired
    private ISysEfficiencyAgentService sysEfficiencyAgent;

    @Autowired
    private ISysDurabilityPerformanceService sysDurabilityPerformanceService;

    @Autowired
    private ISysWaterService waterService;

    @Autowired
    private ISysMineralPowderService sysMineralPowderService;

    @Autowired
    private SysOtherAdmixturesService sysOtherAdmixturesService;


    @Autowired
    private ISysWaterModelService sysWaterModelService;

    @Autowired
    private ISysSwellingagentService sysSwellingagentService;


    @Autowired
    private PlatformVisitService platformVisitService;

    @Autowired
    private PlatformMetricsService platformMetricsService;
    @Autowired
    private ISysSlumpService sysSlumpService;
    @Autowired
    private ISysMechanicalPerformanceService sysMechanicalPerformanceService;

    @Autowired
    private RedisCache redisCache;

    private static final String CACHE_KEY = "homePageData";
    private static final long CACHE_TTL_MINUTES = 10;
    /**
     * 登录事件记录访问接口
     */
    @PostMapping("/sava/platformVisits")
    public AjaxResult login(HttpServletRequest request) {
        String ipAddress = request.getRemoteAddr(); // 获取访问者IP
        String deviceInfo = getDeviceInfo(request);  // 获取设备信息
        String sessionId = request.getSession().getId(); // 获取会话ID
        // 创建访问记录对象
        PlatformVisit visit = new PlatformVisit();
        visit.setUserId(SecurityUtils.getUserId()); // 获取当前用户ID
        visit.setVisitTimestamp(LocalDateTime.now()); // 访问时间
        visit.setIpAddress(ipAddress); // IP地址
        visit.setDeviceInfo(deviceInfo); // 设备信息
        visit.setSessionId(sessionId); // 会话ID
        visit.setCreateBy("system"); // 创建者
        visit.setCreateTime(LocalDateTime.now()); // 创建时间
        // 插入访问记录
        platformVisitService.save(visit);
        // 更新平台总访问次数
        platformMetricsService.incrementTotalVisits();

        return AjaxResult.success("登录访问记录成功");
    }

    /**
     * 提取客户端设备信息（例如：浏览器、操作系统）
     */
    private String getDeviceInfo(HttpServletRequest request) {
        String userAgent = request.getHeader("User-Agent");
        return userAgent != null ? userAgent : "Unknown";
    }


    /**
     * 查询实时访问量（例如：过去 1 小时的访问量）
     *
     * @return 实时访问量
     */
    @GetMapping("/current/visits")
    public AjaxResult getCurrentVisits() {
        // 获取实时访问量
        int realTimeVisitCount = platformVisitService.getRealTimeVisitCount();
        // 返回结果
        return AjaxResult.success("当前实时访问量", realTimeVisitCount);
    }


    /**
     * 查询数据库中各类材料的总数据量
     *
     * @return 返回封装后的 AjaxResult，其中包含总数统计
     */
    @GetMapping("/query/total/database")
    public AjaxResult queryTotalDatabase() {
        // 统计水泥表中的数据条数
        int cementCount = sysCementService.count();

        // 统计石头表中的数据条数
        int stoneCount = sysStoneService.count();

        // 统计砂表中的数据条数
        int sandCount = sysSandService.count();

        // 统计粉煤灰表中的数据条数
        int flyashCount = sysFlyashService.count();

        // 统计矿粉表中的数据条数
        int mineralPowderCount = sysMineralPowderService.count();

        // 统计石粉（其他外加剂）表中的数据条数
        int otherAdmixturesCount = sysOtherAdmixturesService.count();

        // 统计减水剂表中的数据条数
        int waterReducerCount = sysWaterReducerService.count();

        // 统计增效剂表中的数据条数
        int efficiencyAgentCount = sysEfficiencyAgent.count();

        // 统计膨胀剂表中的数据条数
        int swellingAgentCount = sysSwellingagentService.count();

        // 统计力学性能表中的数据条数
        int mechanicalPerformanceCount = sysMechanicalPerformanceService.count();

        // 统计坍落度表中的数据条数
        int slumpCount = sysSlumpService.count();

        // 汇总所有表的数据总量
        int total = cementCount + stoneCount + sandCount + flyashCount +
                mineralPowderCount + otherAdmixturesCount + waterReducerCount +
                efficiencyAgentCount + swellingAgentCount + mechanicalPerformanceCount +
                slumpCount;

        // 返回总数据量，前端可展示为“共计 xxx 条数据”
        return AjaxResult.success("数据库总数据量", total);
    }

    /**
     * 查询平台总访问量
     *
     * @return
     */
    @GetMapping("queryTotalPlatformMetrics")
    public AjaxResult queryTotalPlatformMetrics() {
        LambdaQueryWrapper<PlatformMetrics> queryWrapper = new LambdaQueryWrapper<>();
        PlatformMetrics platformMetrics = platformMetricsService.getOne(queryWrapper, false);
        Long totalVisits = platformMetrics.getTotalVisits();
        return AjaxResult.success(totalVisits);
    }


    /**
     * 查询原材料数据覆盖地区数
     *
     * @return 返回封装后的 AjaxResult，其中包含总数统计
     */
    @GetMapping("/query/total/raw/material/region/size")
    public AjaxResult queryTotalCoveredRegionsRawMaterial() {
        // 各表去重的地区 ID 数
        Set<Integer> regionSet = new HashSet<>();

        regionSet.addAll(sysCementService.list()
                .stream()
                .map(SysCement::getRegionName)
                .filter(Objects::nonNull)
                .collect(Collectors.toSet()));

        regionSet.addAll(sysStoneService.list()
                .stream().map(SysStone::getRegionName).filter(Objects::nonNull).collect(Collectors.toSet()));

        regionSet.addAll(sysSandService.list()
                .stream().map(SysSand::getRegionName).filter(Objects::nonNull).collect(Collectors.toSet()));

        regionSet.addAll(sysFlyashService.list()
                .stream().map(SysFlyash::getRegionName).filter(Objects::nonNull).collect(Collectors.toSet()));

        regionSet.addAll(sysMineralPowderService.list()
                .stream().map(SysMineralPowder::getRegionName).filter(Objects::nonNull).collect(Collectors.toSet()));

        regionSet.addAll(sysOtherAdmixturesService.list()
                .stream().map(SysOtherAdmixtures::getRegionName).filter(Objects::nonNull).collect(Collectors.toSet()));

        int totalCoveredRegions = regionSet.size();

        return AjaxResult.success("原材料数据覆盖地区数", totalCoveredRegions);
    }


    /**
     * 查询总数据覆盖地区数
     *
     * @return 返回封装后的 AjaxResult，其中包含总数统计
     */
    @GetMapping("/query/total/region/size")
    public AjaxResult queryTotalCoveredRegions() {
        // 各表去重的地区 ID 数
        Set<Integer> regionSet = new HashSet<>();

        regionSet.addAll(sysCementService.list()
                .stream()
                .map(SysCement::getRegionName)
                .filter(Objects::nonNull)
                .collect(Collectors.toSet()));

        regionSet.addAll(sysStoneService.list()
                .stream().map(SysStone::getRegionName).filter(Objects::nonNull).collect(Collectors.toSet()));

        regionSet.addAll(sysSandService.list()
                .stream().map(SysSand::getRegionName).filter(Objects::nonNull).collect(Collectors.toSet()));

        regionSet.addAll(sysFlyashService.list()
                .stream().map(SysFlyash::getRegionName).filter(Objects::nonNull).collect(Collectors.toSet()));

        regionSet.addAll(sysMineralPowderService.list()
                .stream().map(SysMineralPowder::getRegionName).filter(Objects::nonNull).collect(Collectors.toSet()));

        regionSet.addAll(sysOtherAdmixturesService.list()
                .stream().map(SysOtherAdmixtures::getRegionName).filter(Objects::nonNull).collect(Collectors.toSet()));

        regionSet.addAll(sysMechanicalPerformanceService.list()
                .stream().map(SysMechanicalPerformance::getRegion).filter(Objects::nonNull).collect(Collectors.toSet()));

        regionSet.addAll(sysSlumpService.list()
                .stream().map(SysSlump::getRegion).filter(Objects::nonNull).collect(Collectors.toSet()));


        int totalCoveredRegions = regionSet.size();

        return AjaxResult.success("原材料和力学性能数据覆盖地区数", totalCoveredRegions);
    }


/**
 * 查询用户最近一个月每天的访问次数
 */


    /**
     * 查询用户最近一个月每天的访问次数
     */
    @GetMapping("/lastMonthVisits")
    public AjaxResult platformVisitList() {
        LocalDate today = LocalDate.now();
        LocalDate startDate = today.minusDays(29); // 包括今天，总共30天

        // 获取指定时间段内的访问记录
        List<PlatformVisit> visitList = platformVisitService.lambdaQuery()
                .ge(PlatformVisit::getVisitTimestamp, startDate.atStartOfDay())
                .le(PlatformVisit::getVisitTimestamp, today.atTime(23, 59, 59))
                .list();

        // 初始化30天的访问计数Map
        Map<String, Integer> dailyCounts = new LinkedHashMap<>();
        for (int i = 0; i < 30; i++) {
            LocalDate date = startDate.plusDays(i);
            dailyCounts.put(date.toString(), 0); // key: yyyy-MM-dd
        }

        // 遍历访问记录，按日期统计
        for (PlatformVisit visit : visitList) {
            LocalDate date = visit.getVisitTimestamp().toLocalDate();
            String dateStr = date.toString();
            dailyCounts.computeIfPresent(dateStr, (k, v) -> v + 1);
        }

        return AjaxResult.success(dailyCounts);
    }

    /**
     * 查询原材料对应的地区
     * @return
     */


    /**
     * 查询地区的数量
     * @return
     */
    @GetMapping("queryrawRegionList")
    public AjaxResult querySysCement() {

        // 查询所有地区
        List<Region> regionList = regionService.list();

        // 构建市级地区Map (level=2)
        Map<Integer, Region> cityMap = regionList.stream()
                .filter(r -> r.getLevel() == 2)
                .collect(Collectors.toMap(Region::getId, r -> r));

        // 构建区县ID(level=3) -> 所属市ID(level=2) 映射
        Map<Integer, Integer> countyToCityMap = new HashMap<>();
        for (Region region : regionList) {
            if (region.getLevel() == 3 && region.getParentId() != null) {
                countyToCityMap.put(region.getId(), region.getParentId());
            } else if (region.getLevel() == 2) {
                countyToCityMap.put(region.getId(), region.getId());  // 市ID映射到自己
            }
        }

        // 查询所有原料数据
        List<SysCement> listCement = sysCementService.list();
        List<SysStone> listStone = sysStoneService.list();
        List<SysSand> listSand = sysSandService.list();
        List<SysFlyash> listFlyash = sysFlyashService.list();
        List<SysMineralPowder> listMineralPowder = sysMineralPowderService.list();
        List<SysOtherAdmixtures> listOtherAdmixtures = sysOtherAdmixturesService.list();

        // 汇总统计（key是市ID）
        Map<Integer, Integer> totalRegionCountMap = new HashMap<>();
        mergeRegionCount(totalRegionCountMap, listCement, countyToCityMap);
        mergeRegionCount(totalRegionCountMap, listStone, countyToCityMap);
        mergeRegionCount(totalRegionCountMap, listSand, countyToCityMap);
        mergeRegionCount(totalRegionCountMap, listFlyash, countyToCityMap);
        mergeRegionCount(totalRegionCountMap, listMineralPowder, countyToCityMap);
        mergeRegionCount(totalRegionCountMap, listOtherAdmixtures, countyToCityMap);

        // 构建结果，只返回市级地区数据
        List<Map<String, Object>> result = new ArrayList<>();
        for (Map.Entry<Integer, Integer> entry : totalRegionCountMap.entrySet()) {
            Integer cityId = entry.getKey();
            Integer count = entry.getValue();
            Region cityRegion = cityMap.get(cityId);
            if (cityRegion != null) {  // 只返回市级地区
                Map<String, Object> item = new HashMap<>();
                item.put("regionId", cityId);
                item.put("regionName", cityRegion.getName());
                item.put("count", count);
                result.add(item);
            }
        }
        int size = result.size();
        System.out.println("原材料地区数"+size);
        return AjaxResult.success(result);
    }

    // 泛型统计方法：将每个物料列表的统计合并到总Map中，key是市ID
    private <T> void mergeRegionCount(Map<Integer, Integer> totalMap, List<T> list, Map<Integer, Integer> countyToCityMap) {
        for (T item : list) {
            try {
                Field regionField = item.getClass().getDeclaredField("regionName");  // 你的实体类中字段名，确认是regionName
                regionField.setAccessible(true);
                Integer regionId = (Integer) regionField.get(item);
                if (regionId != null) {
                    Integer cityId = countyToCityMap.get(regionId);
                    if (cityId != null) {
                        totalMap.put(cityId, totalMap.getOrDefault(cityId, 0) + 1);
                    }
                }
            } catch (NoSuchFieldException | IllegalAccessException e) {
                e.printStackTrace();
            }
        }
    }



/*
    @GetMapping("queryTotalRegionList")
    public AjaxResult queryTotalRegionList() {

        // 查询所有地区
        List<Region> regionList = regionService.list();

        // 构建市级地区Map (level=2)
        Map<Integer, Region> cityMap = regionList.stream()
                .filter(r -> r.getLevel() == 2)
                .collect(Collectors.toMap(Region::getId, r -> r));

        // 构建区县ID(level=3) -> 所属市ID(level=2) 映射
        Map<Integer, Integer> countyToCityMap = new HashMap<>();
        for (Region region : regionList) {
            if (region.getLevel() == 3 && region.getParentId() != null) {
                countyToCityMap.put(region.getId(), region.getParentId());
            } else if (region.getLevel() == 2) {
                countyToCityMap.put(region.getId(), region.getId());  // 市ID映射到自己
            }
        }

        // 查询所有原料数据
        List<SysCement> listCement = sysCementService.list();
        List<SysStone> listStone = sysStoneService.list();
        List<SysSand> listSand = sysSandService.list();
        List<SysFlyash> listFlyash = sysFlyashService.list();
        List<SysMineralPowder> listMineralPowder = sysMineralPowderService.list();
        List<SysOtherAdmixtures> listOtherAdmixtures = sysOtherAdmixturesService.list();

        // 汇总统计（key是市ID）
        Map<Integer, Integer> totalRegionCountMap = new HashMap<>();
        mergeRegionCount(totalRegionCountMap, listCement, countyToCityMap);
        mergeRegionCount(totalRegionCountMap, listStone, countyToCityMap);
        mergeRegionCount(totalRegionCountMap, listSand, countyToCityMap);
        mergeRegionCount(totalRegionCountMap, listFlyash, countyToCityMap);
        mergeRegionCount(totalRegionCountMap, listMineralPowder, countyToCityMap);
        mergeRegionCount(totalRegionCountMap, listOtherAdmixtures, countyToCityMap);

        // 构建结果，只返回市级地区数据
        List<Map<String, Object>> result = new ArrayList<>();
        for (Map.Entry<Integer, Integer> entry : totalRegionCountMap.entrySet()) {
            Integer cityId = entry.getKey();
            Integer count = entry.getValue();
            Region cityRegion = cityMap.get(cityId);
            if (cityRegion != null) {  // 只返回市级地区
                Map<String, Object> item = new HashMap<>();
                item.put("regionId", cityId);
                item.put("regionName", cityRegion.getName());
                item.put("count", count);
                result.add(item);
            }
        }

        return AjaxResult.success(result);
    }
*/




    @GetMapping("queryTotalRegionList")
    public AjaxResult queryTotalRegionList() {
        List<Region> regionList = regionService.list();

        // 市级地区Map
        Map<Integer, Region> cityMap = regionList.stream()
                .filter(r -> r.getLevel() == 2)
                .collect(Collectors.toMap(Region::getId, r -> r));

        // 地区ID -> 市ID映射
        Map<Integer, Integer> regionToCityMap = new HashMap<>();
        for (Region r : regionList) {
            if (r.getLevel() == 3 && r.getParentId() != null) {
                regionToCityMap.put(r.getId(), r.getParentId());
            } else if (r.getLevel() == 2) {
                regionToCityMap.put(r.getId(), r.getId());
            }
        }

        // 各实体列表
        List<? extends Object> allEntities = Stream.of(
                sysCementService.list(),
                sysStoneService.list(),
                sysSandService.list(),
                sysFlyashService.list(),
                sysMineralPowderService.list(),
                sysOtherAdmixturesService.list(),

                sysMechanicalPerformanceService.list(),
                sysSlumpService.list()
        ).flatMap(Collection::stream).collect(Collectors.toList());

        Map<Integer, Integer> totalRegionCountMap = new HashMap<>();
        mergeRegionCountV2(totalRegionCountMap, allEntities, regionToCityMap);

        List<Map<String, Object>> result = new ArrayList<>();
        for (Map.Entry<Integer, Integer> entry : totalRegionCountMap.entrySet()) {
            Region city = cityMap.get(entry.getKey());
            if (city != null) {
                Map<String, Object> map = new HashMap<>();
                map.put("regionId", city.getId());
                map.put("regionName", city.getName());
                map.put("count", entry.getValue());
                result.add(map);
            }
        }
        int size = result.size();
        System.out.println("总地区数"+size);
        return AjaxResult.success(result);
    }

    private <T> void mergeRegionCountV2(Map<Integer, Integer> totalMap, List<T> list, Map<Integer, Integer> regionToCityMap) {
        for (T item : list) {
            try {
                Field regionField = null;
                try {
                    regionField = item.getClass().getDeclaredField("region");
                } catch (NoSuchFieldException e1) {
                    try {
                        regionField = item.getClass().getDeclaredField("regionName");
                    } catch (NoSuchFieldException e2) {
                        System.err.println("Skipping class without region fields: " + item.getClass().getName());
                        continue; // 跳过这个item
                    }
                }

                regionField.setAccessible(true);
                Object val = regionField.get(item);

                Integer regionId = null;
                if (val instanceof Integer) {
                    regionId = (Integer) val;
                } else if (val instanceof String) {
                    try {
                        regionId = Integer.valueOf((String) val);
                    } catch (NumberFormatException ignored) {}
                }

                if (regionId != null) {
                    Integer cityId = regionToCityMap.get(regionId);
                    if (cityId != null) {
                        totalMap.put(cityId, totalMap.getOrDefault(cityId, 0) + 1);
                    }
                }
            } catch (IllegalAccessException e) {
                System.err.println("Illegal access on class: " + item.getClass().getName());
                e.printStackTrace();
            }
        }
    }






    @GetMapping("/todayHourlyVisits")
    public AjaxResult getTodayHourlyVisits() {
        LocalDate today = LocalDate.now();

        // 获取今天0点到现在的访问记录
        List<PlatformVisit> visitList = platformVisitService.lambdaQuery()
                .ge(PlatformVisit::getVisitTimestamp, today.atStartOfDay())
                .le(PlatformVisit::getVisitTimestamp, LocalDateTime.now())
                .list();

        // 初始化24小时统计 Map（0 到 23）
        Map<String, Integer> hourlyCounts = new LinkedHashMap<>();
        for (int hour = 0; hour < 24; hour++) {
            String key = String.format("%02d:00", hour); // eg. 08:00, 13:00
            hourlyCounts.put(key, 0);
        }

        // 遍历访问记录，按小时统计
        for (PlatformVisit visit : visitList) {
            int hour = visit.getVisitTimestamp().getHour();
            String hourStr = String.format("%02d:00", hour);
            hourlyCounts.computeIfPresent(hourStr, (k, v) -> v + 1);
        }

        return AjaxResult.success(hourlyCounts);
    }





    /**
     * 查询数据库首页数据
     *
     * @return
     */

    @GetMapping("queryMonthlyDataCount")
    public AjaxResult queryMonthlyDataCount() {
        int currentYear = Calendar.getInstance().get(Calendar.YEAR);

        // 初始化12个月，每月默认值为0
        Map<Integer, Integer> monthlyData = new TreeMap<>();
        for (int i = 1; i <= 12; i++) {
            monthlyData.put(i, 0);
        }

        // 工具函数：按月份统计
        Function<List<?>, Map<Integer, Integer>> countByMonth = list -> {
            Map<Integer, Integer> result = new HashMap<>();
            for (Object obj : list) {
                try {
                    Object timeObj = obj.getClass().getMethod("getCreateTime").invoke(obj);
                    if (timeObj == null) continue;

                    int year, month;

                    if (timeObj instanceof LocalDateTime) {
                        LocalDateTime localDateTime = (LocalDateTime) timeObj;
                        year = localDateTime.getYear();
                        month = localDateTime.getMonthValue();
                    } else if (timeObj instanceof Date) {
                        Calendar cal = Calendar.getInstance();
                        cal.setTime((Date) timeObj);
                        year = cal.get(Calendar.YEAR);
                        month = cal.get(Calendar.MONTH) + 1;
                    } else {
                        continue;
                    }

                    if (year == currentYear) {
                        result.put(month, result.getOrDefault(month, 0) + 1);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            return result;
        };

        // 获取各表数据
        List<SysCement> cementList = sysCementService.list();
        List<SysStone> stoneList = sysStoneService.list();
        List<SysSand> sandList = sysSandService.list();
        List<SysFlyash> flyashList = sysFlyashService.list();
        List<SysMineralPowder> mineralPowderList = sysMineralPowderService.list();
        List<SysOtherAdmixtures> admixturesList = sysOtherAdmixturesService.list();
        List<SysWaterReducer> reducerList = sysWaterReducerService.list();
        List<SysEfficiencyAgent> agentList = sysEfficiencyAgent.list();
        List<SysSwellingagent> swellingList = sysSwellingagentService.list();
        List<SysMechanicalPerformance> mechList = sysMechanicalPerformanceService.list();
        List<SysSlump> slumpList = sysSlumpService.list();

        // 所有表按月统计
        List<Map<Integer, Integer>> allMonthlyMaps = Arrays.asList(
                countByMonth.apply(cementList),
                countByMonth.apply(stoneList),
                countByMonth.apply(sandList),
                countByMonth.apply(flyashList),
                countByMonth.apply(mineralPowderList),
                countByMonth.apply(admixturesList),
                countByMonth.apply(reducerList),
                countByMonth.apply(agentList),
                countByMonth.apply(swellingList),
                countByMonth.apply(mechList),
                countByMonth.apply(slumpList)
        );

        // 合并统计结果
        for (Map<Integer, Integer> map : allMonthlyMaps) {
            for (Map.Entry<Integer, Integer> entry : map.entrySet()) {
                monthlyData.merge(entry.getKey(), entry.getValue(), Integer::sum);
            }
        }

        return AjaxResult.success(monthlyData);
    }







    /**
     * 统计指定字段去重后的数量（使用 MyBatis-Plus，避免全表查询）
     *
     * @param service    实体服务类（IService）
     * @param columnName 字段名（数据库字段）
     * @return 去重后的记录数
     */
    private <T> int countDistinctRegion(IService<T> service, String columnName) {
        QueryWrapper<T> wrapper = new QueryWrapper<>();
        wrapper.select("DISTINCT " + columnName).isNotNull(columnName);
        List<T> distinctList = service.list(wrapper);
        return distinctList.size();
    }







    @GetMapping("queryHomePageData")
    public AjaxResult queryHomePage() {
        // 先从缓存获取
        Map<String, Object> cachedData = redisCache.getCacheObject(CACHE_KEY);
        if (cachedData != null) {
            return AjaxResult.success(cachedData);
        }

        // 缓存没命中，查询数据库
        int dataTotal = sysCementService.count()
                + sysStoneService.count()
                + sysSandService.count()
                + sysFlyashService.count()
                + sysMineralPowderService.count()
                + sysOtherAdmixturesService.count()
                + sysWaterReducerService.count()
                + sysEfficiencyAgent.count()
                + sysSwellingagentService.count()
                + sysMechanicalPerformanceService.count()
                + sysSlumpService.count();

        int totalCoveredRegions =
                countDistinctRegion(sysCementService, "region_name") +
                        countDistinctRegion(sysStoneService, "region_name") +
                        countDistinctRegion(sysSandService, "region_name") +
                        countDistinctRegion(sysFlyashService, "region_name") +
                        countDistinctRegion(sysMineralPowderService, "region_name") +
                        countDistinctRegion(sysOtherAdmixturesService, "region_name") +
                        countDistinctRegion(sysMechanicalPerformanceService, "region") +
                        countDistinctRegion(sysSlumpService, "region");

        int totalRawmaterialCoveredRegions =
                countDistinctRegion(sysCementService, "region_name") +
                        countDistinctRegion(sysStoneService, "region_name") +
                        countDistinctRegion(sysSandService, "region_name") +
                        countDistinctRegion(sysFlyashService, "region_name") +
                        countDistinctRegion(sysMineralPowderService, "region_name") +
                        countDistinctRegion(sysOtherAdmixturesService, "region_name");

        Long totalVisits = Optional.ofNullable(platformMetricsService.getOne(null, false))
                .map(PlatformMetrics::getTotalVisits)
                .orElse(0L);
        int realTimeVisitCount = platformVisitService.getRealTimeVisitCount();

        Map<String, Object> map = new HashMap<>();
        map.put("dataTotal", dataTotal);
        map.put("dataParm", 91);
        map.put("totalCoveredRegions", totalCoveredRegions);
        map.put("totalRawmaterialCoveredRegions", totalRawmaterialCoveredRegions);
        map.put("totalVisits", totalVisits);
        map.put("realTimeVisitCount", realTimeVisitCount);

        // 缓存10分钟
        redisCache.setCacheObject(CACHE_KEY, map, (int) CACHE_TTL_MINUTES, TimeUnit.MINUTES);

        return AjaxResult.success(map);
    }







    /**
     * 查询数据库首页数据
     *
     * @return
     */
/*666 好的
    @GetMapping("queryHomePageData")
    public AjaxResult queryHomePage() {
        //数据库总数据量
        // 统计水泥表中的数据条数
        int cementCount = sysCementService.count();

        // 统计石头表中的数据条数
        int stoneCount = sysStoneService.count();

        // 统计砂表中的数据条数
        int sandCount = sysSandService.count();

        // 统计粉煤灰表中的数据条数
        int flyashCount = sysFlyashService.count();

        // 统计矿粉表中的数据条数
        int mineralPowderCount = sysMineralPowderService.count();

        // 统计石粉（其他外加剂）表中的数据条数
        int otherAdmixturesCount = sysOtherAdmixturesService.count();

        // 统计减水剂表中的数据条数
        int waterReducerCount = sysWaterReducerService.count();

        // 统计增效剂表中的数据条数
        int efficiencyAgentCount = sysEfficiencyAgent.count();

        // 统计膨胀剂表中的数据条数
        int swellingAgentCount = sysSwellingagentService.count();

        // 统计力学性能表中的数据条数
        int mechanicalPerformanceCount = sysMechanicalPerformanceService.count();

        // 统计坍落度表中的数据条数
        int slumpCount = sysSlumpService.count();

        // 汇总所有表的数据总量
        int dataTotal = cementCount + stoneCount + sandCount + flyashCount +
                mineralPowderCount + otherAdmixturesCount + waterReducerCount +
                efficiencyAgentCount + swellingAgentCount + mechanicalPerformanceCount +
                slumpCount;


        //数据库涉及参数量
        //数据覆盖地区数
        // 各表去重的地区 ID 数
        Set<Integer> regionSet = new HashSet<>();

        regionSet.addAll(sysCementService.list()
                .stream()
                .map(SysCement::getRegionName)
                .filter(Objects::nonNull)
                .collect(Collectors.toSet()));

        regionSet.addAll(sysStoneService.list()
                .stream().map(SysStone::getRegionName).filter(Objects::nonNull).collect(Collectors.toSet()));

        regionSet.addAll(sysSandService.list()
                .stream().map(SysSand::getRegionName).filter(Objects::nonNull).collect(Collectors.toSet()));

        regionSet.addAll(sysFlyashService.list()
                .stream().map(SysFlyash::getRegionName).filter(Objects::nonNull).collect(Collectors.toSet()));

        regionSet.addAll(sysMineralPowderService.list()
                .stream().map(SysMineralPowder::getRegionName).filter(Objects::nonNull).collect(Collectors.toSet()));

        regionSet.addAll(sysOtherAdmixturesService.list()
                .stream().map(SysOtherAdmixtures::getRegionName).filter(Objects::nonNull).collect(Collectors.toSet()));

        regionSet.addAll(sysMechanicalPerformanceService.list()
                .stream().map(SysMechanicalPerformance::getRegion).filter(Objects::nonNull).collect(Collectors.toSet()));

        regionSet.addAll(sysSlumpService.list()
                .stream().map(SysSlump::getRegion).filter(Objects::nonNull).collect(Collectors.toSet()));


        int totalCoveredRegions = regionSet.size();
        //原材料数据覆盖地区数
        // 各表去重的地区 ID 数
        Set<Integer> regionSet1 = new HashSet<>();

        regionSet1.addAll(sysCementService.list()
                .stream()
                .map(SysCement::getRegionName)
                .filter(Objects::nonNull)
                .collect(Collectors.toSet()));

        regionSet1.addAll(sysStoneService.list()
                .stream().map(SysStone::getRegionName).filter(Objects::nonNull).collect(Collectors.toSet()));

        regionSet1.addAll(sysSandService.list()
                .stream().map(SysSand::getRegionName).filter(Objects::nonNull).collect(Collectors.toSet()));

        regionSet1.addAll(sysFlyashService.list()
                .stream().map(SysFlyash::getRegionName).filter(Objects::nonNull).collect(Collectors.toSet()));

        regionSet1.addAll(sysMineralPowderService.list()
                .stream().map(SysMineralPowder::getRegionName).filter(Objects::nonNull).collect(Collectors.toSet()));

        regionSet1.addAll(sysOtherAdmixturesService.list()
                .stream().map(SysOtherAdmixtures::getRegionName).filter(Objects::nonNull).collect(Collectors.toSet()));

        int totalRawmaterialCoveredRegions = regionSet1.size();
        //平台总访问次数
        LambdaQueryWrapper<PlatformMetrics> queryWrapper = new LambdaQueryWrapper<>();
        PlatformMetrics platformMetrics = platformMetricsService.getOne(queryWrapper, false);
        Long totalVisits = platformMetrics.getTotalVisits();
        //平台实时访问量
        // 获取实时访问量
        int realTimeVisitCount = platformVisitService.getRealTimeVisitCount();
        HashMap<String, Object> map = new HashMap<>();
        map.put("dataTotal", dataTotal);   //数据库总数据量
        map.put("dataParm", 91);//数据库涉及参数量
        map.put("totalCoveredRegions", totalCoveredRegions);       //数据覆盖地区数
        map.put("totalRawmaterialCoveredRegions", totalRawmaterialCoveredRegions);        //原材料数据覆盖地区数
        map.put("totalVisits", totalVisits);        //平台总访问次数
        map.put("realTimeVisitCount", realTimeVisitCount);   //平台实时访问量

        return AjaxResult.success(map);
    }
*/


/*
    @GetMapping("queryHomePageData")
    public AjaxResult queryHomePage() {
        //数据库总数据量
        // 统计水泥表中的数据条数
        int cementCount = sysCementService.count();

        // 统计石头表中的数据条数
        int stoneCount = sysStoneService.count();

        // 统计砂表中的数据条数
        int sandCount = sysSandService.count();

        // 统计粉煤灰表中的数据条数
        int flyashCount = sysFlyashService.count();

        // 统计矿粉表中的数据条数
        int mineralPowderCount = sysMineralPowderService.count();

        // 统计石粉（其他外加剂）表中的数据条数
        int otherAdmixturesCount = sysOtherAdmixturesService.count();

        // 统计减水剂表中的数据条数
        int waterReducerCount = sysWaterReducerService.count();

        // 统计增效剂表中的数据条数
        int efficiencyAgentCount = sysEfficiencyAgent.count();

        // 统计膨胀剂表中的数据条数
        int swellingAgentCount = sysSwellingagentService.count();

        // 统计力学性能表中的数据条数
        int mechanicalPerformanceCount = sysMechanicalPerformanceService.count();

        // 统计坍落度表中的数据条数
        int slumpCount = sysSlumpService.count();

        // 汇总所有表的数据总量
        int dataTotal = cementCount + stoneCount + sandCount + flyashCount +
                mineralPowderCount + otherAdmixturesCount + waterReducerCount +
                efficiencyAgentCount + swellingAgentCount + mechanicalPerformanceCount +
                slumpCount;


        //数据库涉及参数量
        //数据覆盖地区数
        // 各表去重的地区 ID 数
        Set<Integer> regionSet = new HashSet<>();

        regionSet.addAll(sysCementService.list()
                .stream()
                .map(SysCement::getRegionName)
                .filter(Objects::nonNull)
                .collect(Collectors.toSet()));

        regionSet.addAll(sysStoneService.list()
                .stream().map(SysStone::getRegionName).filter(Objects::nonNull).collect(Collectors.toSet()));

        regionSet.addAll(sysSandService.list()
                .stream().map(SysSand::getRegionName).filter(Objects::nonNull).collect(Collectors.toSet()));

        regionSet.addAll(sysFlyashService.list()
                .stream().map(SysFlyash::getRegionName).filter(Objects::nonNull).collect(Collectors.toSet()));

        regionSet.addAll(sysMineralPowderService.list()
                .stream().map(SysMineralPowder::getRegionName).filter(Objects::nonNull).collect(Collectors.toSet()));

        regionSet.addAll(sysOtherAdmixturesService.list()
                .stream().map(SysOtherAdmixtures::getRegionName).filter(Objects::nonNull).collect(Collectors.toSet()));

        regionSet.addAll(sysMechanicalPerformanceService.list()
                .stream().map(SysMechanicalPerformance::getRegion).filter(Objects::nonNull).collect(Collectors.toSet()));

        regionSet.addAll(sysSlumpService.list()
                .stream().map(SysSlump::getRegion).filter(Objects::nonNull).collect(Collectors.toSet()));


        int totalCoveredRegions = regionSet.size();
        //原材料数据覆盖地区数
        // 各表去重的地区 ID 数
        Set<Integer> regionSet1 = new HashSet<>();

        regionSet1.addAll(sysCementService.list()
                .stream()
                .map(SysCement::getRegionName)
                .filter(Objects::nonNull)
                .collect(Collectors.toSet()));

        regionSet1.addAll(sysStoneService.list()
                .stream().map(SysStone::getRegionName).filter(Objects::nonNull).collect(Collectors.toSet()));

        regionSet1.addAll(sysSandService.list()
                .stream().map(SysSand::getRegionName).filter(Objects::nonNull).collect(Collectors.toSet()));

        regionSet1.addAll(sysFlyashService.list()
                .stream().map(SysFlyash::getRegionName).filter(Objects::nonNull).collect(Collectors.toSet()));

        regionSet1.addAll(sysMineralPowderService.list()
                .stream().map(SysMineralPowder::getRegionName).filter(Objects::nonNull).collect(Collectors.toSet()));

        regionSet1.addAll(sysOtherAdmixturesService.list()
                .stream().map(SysOtherAdmixtures::getRegionName).filter(Objects::nonNull).collect(Collectors.toSet()));

        int totalRawmaterialCoveredRegions = regionSet1.size();
        //平台总访问次数
        LambdaQueryWrapper<PlatformMetrics> queryWrapper = new LambdaQueryWrapper<>();
        PlatformMetrics platformMetrics = platformMetricsService.getOne(queryWrapper, false);
        Long totalVisits = platformMetrics.getTotalVisits();
        //平台实时访问量
        // 获取实时访问量
        int realTimeVisitCount = platformVisitService.getRealTimeVisitCount();
        HashMap<String, Object> map = new HashMap<>();
        map.put("dataTotal", dataTotal);   //数据库总数据量
        map.put("dataParm", 91);//数据库涉及参数量
        map.put("totalCoveredRegions", totalCoveredRegions);       //数据覆盖地区数
        map.put("totalRawmaterialCoveredRegions", totalRawmaterialCoveredRegions);        //原材料数据覆盖地区数
        map.put("totalVisits", totalVisits);        //平台总访问次数
        map.put("realTimeVisitCount", realTimeVisitCount);   //平台实时访问量

        return AjaxResult.success(map);
    }
*/


    /**
     * 查询总数据量 本月和上月
     */
/*
    @GetMapping("/queryDailyDataThisAndLastMonth")
    public AjaxResult queryDailyDataThisAndLastMonth() {
        Map<String, List<Object>> currentMonthData = getDailyTotalForMonth(LocalDate.now());
        Map<String, List<Object>> lastMonthData = getDailyTotalForMonth(LocalDate.now().minusMonths(1));

        Map<String, Object> result = new HashMap<>();
        result.put("currentMonth", currentMonthData);
        result.put("lastMonth", lastMonthData);

        return AjaxResult.success(result);
    }

    private Map<String, List<Object>> getDailyTotalForMonth(LocalDate month) {
        LocalDate firstDay = month.withDayOfMonth(1);
        LocalDate lastDay = month.withDayOfMonth(month.lengthOfMonth());
        LocalDateTime monthStart = firstDay.atStartOfDay();
        LocalDateTime monthEnd = lastDay.plusDays(1).atStartOfDay();

        List<Map<LocalDate, Integer>> countMaps = Arrays.asList(
                countByDate(fetchCreateTimes(sysCementService, monthStart, monthEnd)),
                countByDate(fetchCreateTimes(sysStoneService, monthStart, monthEnd)),
                countByDate(fetchCreateTimes(sysSandService, monthStart, monthEnd)),
                countByDate(fetchCreateTimes(sysFlyashService, monthStart, monthEnd)),
                countByDate(fetchCreateTimes(sysMineralPowderService, monthStart, monthEnd)),
                countByDate(fetchCreateTimes(sysOtherAdmixturesService, monthStart, monthEnd)),
                countByDate(fetchCreateTimes(sysWaterReducerService, monthStart, monthEnd)),
                countByDate(fetchCreateTimes(sysEfficiencyAgent, monthStart, monthEnd)),
                countByDate(fetchCreateTimes(sysSwellingagentService, monthStart, monthEnd)),
                countByDate(fetchCreateTimes(sysMechanicalPerformanceService, monthStart, monthEnd)),
                countByDate(fetchCreateTimes(sysSlumpService, monthStart, monthEnd))
        );

        Map<LocalDate, Integer> totalCountMap = new HashMap<>();
        for (Map<LocalDate, Integer> map : countMaps) {
            for (Map.Entry<LocalDate, Integer> entry : map.entrySet()) {
                totalCountMap.put(entry.getKey(), totalCountMap.getOrDefault(entry.getKey(), 0) + entry.getValue());
            }
        }

        List<Object> dateList = new ArrayList<>();
        List<Object> countList = new ArrayList<>();
        for (LocalDate date = firstDay; !date.isAfter(lastDay); date = date.plusDays(1)) {
            dateList.add(date.toString());
            countList.add(totalCountMap.getOrDefault(date, 0));
        }

        Map<String, List<Object>> result = new HashMap<>();
        result.put("date", dateList);
        result.put("count", countList);
        return result;
    }

*/


    private Map<LocalDate, Integer> countByDate(List<LocalDateTime> times) {
        Map<LocalDate, Integer> countMap = new HashMap<>();
        if (times == null || times.isEmpty()) {
            return countMap;
        }
        for (LocalDateTime time : times) {
            if (time == null) {
                continue;
            }
            LocalDate date = time.toLocalDate();
            countMap.put(date, countMap.getOrDefault(date, 0) + 1);
        }
        return countMap;
    }


/*
    @GetMapping("/queryDailyDataThisAndLastMonth")
    public AjaxResult queryDailyDataThisAndLastMonth() {
        Map<String, Integer> currentMonthData = getDailyTotalForMonth(LocalDate.now());
        Map<String, Integer> lastMonthData = getDailyTotalForMonth(LocalDate.now().minusMonths(1));

        Map<String, Object> result = new HashMap<>();
        result.put("currentMonth", currentMonthData);
        result.put("lastMonth", lastMonthData);

        return AjaxResult.success(result);
    }

    private Map<String, Integer> getDailyTotalForMonth(LocalDate month) {
        LocalDate firstDay = month.withDayOfMonth(1);
        LocalDate lastDay = month.withDayOfMonth(month.lengthOfMonth());

        Map<String, Integer> dailyTotal = new TreeMap<>();

        for (LocalDate date = firstDay; !date.isAfter(lastDay); date = date.plusDays(1)) {
            LocalDateTime start = date.atStartOfDay();
            LocalDateTime end = date.plusDays(1).atStartOfDay();

            int totalCount =
                    sysCementService.count(new LambdaQueryWrapper<SysCement>()
                            .ge(SysCement::getCreateTime, start)
                            .lt(SysCement::getCreateTime, end)) +
                            sysStoneService.count(new LambdaQueryWrapper<SysStone>()
                                    .ge(SysStone::getCreateTime, start)
                                    .lt(SysStone::getCreateTime, end)) +
                            sysSandService.count(new LambdaQueryWrapper<SysSand>()
                                    .ge(SysSand::getCreateTime, start)
                                    .lt(SysSand::getCreateTime, end)) +
                            sysFlyashService.count(new LambdaQueryWrapper<SysFlyash>()
                                    .ge(SysFlyash::getCreateTime, start)
                                    .lt(SysFlyash::getCreateTime, end)) +
                            sysMineralPowderService.count(new LambdaQueryWrapper<SysMineralPowder>()
                                    .ge(SysMineralPowder::getCreateTime, start)
                                    .lt(SysMineralPowder::getCreateTime, end)) +
                            sysOtherAdmixturesService.count(new LambdaQueryWrapper<SysOtherAdmixtures>()
                                    .ge(SysOtherAdmixtures::getCreateTime, start)
                                    .lt(SysOtherAdmixtures::getCreateTime, end)) +
                            sysWaterReducerService.count(new LambdaQueryWrapper<SysWaterReducer>()
                                    .ge(SysWaterReducer::getCreateTime, start)
                                    .lt(SysWaterReducer::getCreateTime, end)) +
                            sysEfficiencyAgent.count(new LambdaQueryWrapper<SysEfficiencyAgent>()
                                    .ge(SysEfficiencyAgent::getCreateTime, start)
                                    .lt(SysEfficiencyAgent::getCreateTime, end)) +
                            sysSwellingagentService.count(new LambdaQueryWrapper<SysSwellingagent>()
                                    .ge(SysSwellingagent::getCreateTime, start)
                                    .lt(SysSwellingagent::getCreateTime, end)) +
                            sysMechanicalPerformanceService.count(new LambdaQueryWrapper<SysMechanicalPerformance>()
                                    .ge(SysMechanicalPerformance::getCreateTime, start)
                                    .lt(SysMechanicalPerformance::getCreateTime, end)) +
                            sysSlumpService.count(new LambdaQueryWrapper<SysSlump>()
                                    .ge(SysSlump::getCreateTime, start)
                                    .lt(SysSlump::getCreateTime, end));

            dailyTotal.put(date.toString(), totalCount);
        }

        return dailyTotal;
    }

*/


//    @GetMapping("/queryTotalDatabaseCurrentMonthLastMonth")
//    public AjaxResult queryTotalDatabaseCurrentMonthLastMonth() {
//        // 统计水泥表中的数据条数
//        int cementCount = sysCementService.count();
//
//        // 统计石头表中的数据条数
//        int stoneCount = sysStoneService.count();
//
//        // 统计砂表中的数据条数
//        int sandCount = sysSandService.count();
//
//        // 统计粉煤灰表中的数据条数
//        int flyashCount = sysFlyashService.count();
//
//        // 统计矿粉表中的数据条数
//        int mineralPowderCount = sysMineralPowderService.count();
//
//        // 统计石粉（其他外加剂）表中的数据条数
//        int otherAdmixturesCount = sysOtherAdmixturesService.count();
//
//        // 统计减水剂表中的数据条数
//        int waterReducerCount = sysWaterReducerService.count();
//
//        // 统计增效剂表中的数据条数
//        int efficiencyAgentCount = sysEfficiencyAgent.count();
//
//        // 统计膨胀剂表中的数据条数
//        int swellingAgentCount = sysSwellingagentService.count();
//
//        // 统计力学性能表中的数据条数
//        int mechanicalPerformanceCount = sysMechanicalPerformanceService.count();
//
//        // 统计坍落度表中的数据条数
//        int slumpCount = sysSlumpService.count();
//
//        // 汇总所有表的数据总量
//        int total = cementCount + stoneCount + sandCount + flyashCount +
//                mineralPowderCount + otherAdmixturesCount + waterReducerCount +
//                efficiencyAgentCount + swellingAgentCount + mechanicalPerformanceCount +
//                slumpCount;
//
//        // 返回总数据量，前端可展示为“共计 xxx 条数据”
//
//        return ;
//    }


}
